package com.ssoserver.config;

import com.ssoserver.annotation.MyDataSource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
@Order(1)//此处将该优先级设置最高 以防出现数据源切换异常
@Slf4j
public class DataSourceAspect {
    @Pointcut("@annotation(com.ssoserver.annotation.MyDataSource)")
    public void dbPointcut() {
    }

    /**
     * 也可通过该方式获取注解内容   &&@annotation(dataSource)
     * @param point
     */
    @Before(value = "dbPointcut()")
    public void beforeSwitch(JoinPoint point) {
        //获得当前class的名字
        Class<?> className = point.getTarget().getClass();
        //获得访问的方法名
        String methodName = point.getSignature().getName();
        //获得方法的参数类型
        Class[] classTypes = ((MethodSignature) point.getSignature()).getParameterTypes();
        //默认数据源
        String defaultDataSource = "master";
        try {
            //得到访问方法的对象
            Method method = className.getMethod(methodName, classTypes);
            //判断该方法是否包含该注解
            if (method.isAnnotationPresent(MyDataSource.class)) {
                MyDataSource annotation = method.getAnnotation(MyDataSource.class);
                //去除注解中的数据源
                defaultDataSource = annotation.value();
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("数据源切换异常");
        }
        log.info("当前数据源为：{}", defaultDataSource);
        //切换数据源
        DatabaseHolder.setDataSource(defaultDataSource);
    }

    @After("dbPointcut()")
    public void afterSwitch(JoinPoint joinPoint) {
        DatabaseHolder.clearDataSource();
    }
}
